﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.ImportMFGsFromFile.CApImportMFGsFromFileInternal
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.ImportMFGsFromFile.Resources;
using EngineeringInternalExtension;
using EngineeringInternalExtension.Viewers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Resources;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.DataTypes;
using Tecnomatix.Engineering.PrivateImplementationDetails;
using Tecnomatix.Planning;


namespace DnProcessSimulateCommands.ImportMFGsFromFile;

public class CApImportMFGsFromFileInternal
{
  private const double MAX_TRANSLATION_VALUE = 999999.0;
  private const double MIN_TRANSLATION_VALUE = -999999.0;
  private const double TRANSLATION_EPS = 0.001;
  private int warningsNumber;
  private int errorsNumber;
  private const string DELIMITER = "------------------------------------------------";
  private const string WELD_POINT_TYPE = "PmWeldPoint";
  private const string WELD_POINT_ITEM_TYPE = "WeldPoint";
  private const string WELD_POINT_REVISION_TYPE = "WeldPointRevision";
  private BitmapImage warningIco;
  private BitmapImage errorIco;
  private BitmapImage successIco;
  private CApIMFFCSVParser parser;
  private ResourceManager resMgr;
  public static char CSV_DELIMITER = ',';
  public static char CSV_GROUP_SYMBOL = '"';
  private CApIMFFLogManager logger;
  private static string lastBrowserDir = TxApplication.SystemRootDirectoryNormalized;
  private string csvFileName = "";
  private List<ITxObject> partsUnderPhysicalRoot;
  private List<Tuple<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int>> weldPointsList = new List<Tuple<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int>>();
  private Dictionary<string, List<ITxObject>> existingMfgs = new Dictionary<string, List<ITxObject>>();
  private Dictionary<string, int> weldPointsNumberToImport = new Dictionary<string, int>();
  private SortedDictionary<IMFFLogCode, List<string>> errors = new SortedDictionary<IMFFLogCode, List<string>>();
  private SortedDictionary<IMFFLogCode, List<string>> warnings = new SortedDictionary<IMFFLogCode, List<string>>();
  private SortedDictionary<IMFFLogCode, List<string>> infos = new SortedDictionary<IMFFLogCode, List<string>>();
  private AttributesManager attributesManager = new AttributesManager();
  private Dictionary<string, List<string>> m_csvFileNameToWeldPointsNames = new Dictionary<string, List<string>>();
  private Dictionary<string, TxBaseWeldOperation> m_csvFileNameToWeldOperation = new Dictionary<string, TxBaseWeldOperation>();
  private HashSet<string> m_csvFilesSuccessfullyParsed = new HashSet<string>();
  private TxOperationTreeInternal txOperationTree = new TxOperationTreeInternal();

  internal event OnWarningDetectedEventHandler onWarningDetected;

  internal event OnErrorDetectedEventHandler onErrorDetected;

  internal event OnMFGImportedEventHandler onMFGImported;

  internal event OnImportStatusChangedEventHandler onImportStatusChanged;

  public int MFGsCreatedNumber { get; private set; }

  public int MFGsUpdatedNumber { get; private set; }

  public int LinesParsed { get; private set; }

  public bool UseWorkingFrame { get; set; }

  public ImportMode CommandMode { get; set; }

  public void Initialize()
  {
    this.ClearMembers();
    this.InitLogger(this.LogPathLocation);
    this.FireOnImportStatusChanged(ImportStatus.Initializing);
  }

  public void FinishImport()
  {
    this.LogMessages(this.ResourceMgr.GetString("IMFF_ERRORS"), this.errors, this.ErrorCodesToLogInParsingPhase);
    this.PrintSummary();
    this.FinalizeLogger();
    this.FireOnImportStatusChanged(ImportStatus.Finished);
  }

  public void ImportFiles(string[] filesToImport)
  {
    this.Initialize();
    try
    {
      this.txOperationTree.FreezeTree();
      TxApplication.ActiveUndoManager.StartTransaction();
      foreach (string filePath in filesToImport)
        this.Act(filePath);
      foreach (KeyValuePair<string, List<string>> toWeldPointsName in this.m_csvFileNameToWeldPointsNames)
      {
        int count = toWeldPointsName.Value != null ? toWeldPointsName.Value.Count : 0;
        CApImportMFGsAnalytics.LogImportMfgFile(toWeldPointsName.Key, count);
      }
    }
    finally
    {
      this.CreateWeldPointsInTuneByCreationData();
      TxApplication.ActiveUndoManager.EndTransaction();
      this.FinishImport();
    }
  }

  public void Act(string filePath)
  {
    this.csvFileName = filePath;
    if (this.csvFileName == null)
      return;
    this.LogCurrentFile(this.csvFileName);
    this.InitParser();
    try
    {
      this.LogMessage(this.ResourceMgr.GetString("IMFF_PARSING"));
      this.FireOnImportStatusChanged(ImportStatus.ParsingFile);
      if (this.parser.ParseCSVFile(this.csvFileName))
      {
        this.m_csvFilesSuccessfullyParsed.Add(this.csvFileName);
        string withoutExtension = Path.GetFileNameWithoutExtension(this.csvFileName);
        TxBaseWeldOperation operationContainer = this.CreateWeldOperationContainer(withoutExtension);
        if (TxBaseWeldOperation.op_Inequality(operationContainer, (ITxObject) null))
          this.m_csvFileNameToWeldOperation.Add(withoutExtension, operationContainer);
        this.LogMessages(this.ResourceMgr.GetString("IMFF_PARSING_WARNINGS_OCCURED"), this.warnings, this.WarningCodesToLogInParsingPhase);
        this.LogMessage(this.ResourceMgr.GetString("IMFF_PARSING_FINISHED"));
        this.LogMessage("------------------------------------------------");
      }
      else
        this.LogMessages(this.ResourceMgr.GetString("IMFF_PARSING_WARNINGS_OCCURED"), this.warnings, this.WarningCodesToLogInParsingPhase);
    }
    catch (Exception ex)
    {
      this.AddWarningError(IMFFLogCode.GENERAL_ERROR, ex.Message);
    }
    finally
    {
      this.FinalizeParser();
    }
  }

  private HashSet<string> GetDiscreteOperationTypes()
  {
    TxPlanningTypeMetaData typeMetaData = TxApplication.ActiveDocument.PlatformGlobalServicesProvider.GetTypeMetaData("Mfg0MEDiscreteOPRevision");
    return (typeMetaData != null ? typeMetaData.DerivedTypes.Cast<TxPlanningTypeMetaData>().Select<TxPlanningTypeMetaData, string>((Func<TxPlanningTypeMetaData, string>) (t => t.TypeName)).ToHashSet<string>() : (HashSet<string>) null) ?? new HashSet<string>();
  }

  private string GetFirstAllowedDiscreteOperatopnType(
    ITxProcessModelObject modelObject,
    HashSet<string> discreteTypes)
  {
    foreach (string discreteOperatopnType in (modelObject.PlanningRepresentation.PlatformServicesProvider is ITxTcAnyServicesProvider servicesProvider ? servicesProvider.AllowedChildrenTypes.Select<TxPlanningTypeMetaData, string>((Func<TxPlanningTypeMetaData, string>) (t => t.TypeName)) : (IEnumerable<string>) null) ?? (IEnumerable<string>) new List<string>())
    {
      if (discreteTypes.Contains(discreteOperatopnType))
        return discreteOperatopnType;
    }
    return (string) null;
  }

  private static string GenerateOperationName(string fileName)
  {
    DateTime now = DateTime.Now;
    CultureInfo currentCulture = CultureInfo.CurrentCulture;
    return $"{fileName} - {now.ToString((IFormatProvider) currentCulture)}";
  }

  private TxBaseWeldOperation CreateWeldOperationContainer(string csvFileName)
  {
    string operationName = CApImportMFGsFromFileInternal.GenerateOperationName(csvFileName);
    TxBaseWeldOperation operationContainer = (TxBaseWeldOperation) null;
    ITxOperation[] array = ((IEnumerable) TxApplication.ActiveSelection.GetItems()).OfType<ITxOperation>().ToArray<ITxOperation>();
    ITxObject itxObject = array.Length == 0 ? this.GetParentOperationToCreateWeldOperationsUnder() : (ITxObject) array[0];
    HashSet<string> discreteOperationTypes = this.GetDiscreteOperationTypes();
    for (; itxObject != null; itxObject = (ITxObject) itxObject.Collection)
    {
      if (itxObject is ITxProcessModelObject modelObject)
      {
        string discreteOperatopnType = this.GetFirstAllowedDiscreteOperatopnType(modelObject, discreteOperationTypes);
        if (!string.IsNullOrEmpty(discreteOperatopnType) && itxObject is ITxTcOperationCreation operationCreation)
        {
          using (TxTcDiscreteOperationCreationData operationCreationData = new TxTcDiscreteOperationCreationData(operationName)
          {
            TypeName = discreteOperatopnType
          })
          {
            if (operationCreation.CanCreateTcDiscreteOperation(operationCreationData))
            {
              operationContainer = (TxBaseWeldOperation) operationCreation.CreateTcDiscreteOperation(operationCreationData);
              break;
            }
          }
        }
      }
      if (itxObject is ITxOperationCreation operationCreation1 && operationCreation1.CanCreateChildOperationOfType(typeof (TxWeldOperation)))
      {
        using (TxWeldOperationCreationData operationCreationData = new TxWeldOperationCreationData(operationName))
        {
          operationContainer = (TxBaseWeldOperation) operationCreation1.CreateWeldOperation(operationCreationData);
          break;
        }
      }
    }
    return operationContainer;
  }

  public CApImportMFGsFromFileInternal()
  {
    this.resMgr = new ResourceManager("DnProcessSimulateCommands.ImportMFGsFromFile.Resources.IMFFResources", this.GetType().Assembly);
    this.warningsNumber = 0;
    this.errorsNumber = 0;
    this.CommandMode = ImportMode.NOT_DEFINED;
  }

  public void OpenLogFile() => Process.Start(this.LogPathLocation);

  public string[] GetFilesPath()
  {
    string[] filesPath = (string[]) null;
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
    {
      openFileDialog.InitialDirectory = this.LastBrowsedDirectory;
      openFileDialog.Title = this.ResourceMgr.GetString("IMFF_BROWSE_FILE");
      openFileDialog.CheckPathExists = true;
      openFileDialog.CheckFileExists = true;
      openFileDialog.Multiselect = true;
      openFileDialog.Filter = "CSV (Comma separated values) (*.csv)|*.csv|All files (*.*)|*.*";
      if (openFileDialog.ShowDialog() == DialogResult.OK)
      {
        filesPath = openFileDialog.FileNames;
        this.LastBrowsedDirectory = Path.GetDirectoryName(filesPath[filesPath.Length - 1]);
      }
    }
    return filesPath;
  }

  public DialogResult ShowConfirmMessage()
  {
    return TxMessageBox.Show(this.ResourceMgr.GetString("IMFF_OVERWRITE_CONFIRM"), this.ResourceMgr.GetString("IMFF_NAME"), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
  }

  public static BitmapImage GetImage(string uri) => new BitmapImage(new Uri(uri));

  public string GetSummaryMessage()
  {
    string summaryMessage;
    if (this.CommandMode == ImportMode.CANCEL)
    {
      summaryMessage = this.errorsNumber != 1 ? string.Format(this.ResourceMgr.GetString("IMFF_IMPORT_FAILED"), (object) this.errorsNumber) : string.Format(this.ResourceMgr.GetString("IMFF_IMPORT_FAILED_SINGULAR"), (object) this.errorsNumber);
    }
    else
    {
      string str = this.warningsNumber > 0 || this.errorsNumber > 0 ? (this.warningsNumber != 1 || this.errorsNumber != 1 ? (this.warningsNumber != 1 ? (this.errorsNumber != 1 ? string.Format(this.ResourceMgr.GetString("IMFF_WAR_ERR_FINISHED"), (object) this.warningsNumber, (object) this.errorsNumber) : string.Format(this.ResourceMgr.GetString("IMFF_WAR_ERR_FINISHED_ERR_SINGULAR"), (object) this.warningsNumber, (object) this.errorsNumber)) : string.Format(this.ResourceMgr.GetString("IMFF_WAR_ERR_FINISHED_WAR_SINGULAR"), (object) this.warningsNumber, (object) this.errorsNumber)) : string.Format(this.ResourceMgr.GetString("IMFF_WAR_ERR_FINISHED_BOTH_SINGULAR"), (object) this.warningsNumber, (object) this.errorsNumber)) : this.ResourceMgr.GetString("IMFF_SUCCESSFULLY_FINISHED");
      summaryMessage = this.MFGsCreatedNumber != 1 ? $"{str} {string.Format(this.ResourceMgr.GetString("IMFF_MFGS_IMPORTED"), (object) this.MFGsCreatedNumber)}" : $"{str} {string.Format(this.ResourceMgr.GetString("IMFF_MFGS_IMPORTED_SINGULAR"), (object) this.MFGsCreatedNumber)}";
      if (this.MFGsUpdatedNumber > 0)
        summaryMessage = this.MFGsUpdatedNumber != 1 ? $"{summaryMessage} {string.Format(this.ResourceMgr.GetString("IMFF_MFGS_UPDATED"), (object) this.MFGsUpdatedNumber)}" : $"{summaryMessage} {string.Format(this.ResourceMgr.GetString("IMFF_MFGS_UPDATED_SINGULAR"), (object) this.MFGsUpdatedNumber)}";
    }
    return summaryMessage;
  }

  public BitmapImage SuccessIcon
  {
    get
    {
      if (this.successIco == null)
        this.successIco = CApImportMFGsFromFileInternal.GetImage("pack://application:,,,/DnProcessSimulateCommands;component/ImportMFGsFromFile/Resources/valid.ico");
      return this.successIco;
    }
  }

  public BitmapImage WarningIcon
  {
    get
    {
      if (this.warningIco == null)
        this.warningIco = CApImportMFGsFromFileInternal.GetImage("pack://application:,,,/DnProcessSimulateCommands;component/ImportMFGsFromFile/Resources/warning.ico");
      return this.warningIco;
    }
  }

  public BitmapImage ErrorIcon
  {
    get
    {
      if (this.errorIco == null)
        this.errorIco = CApImportMFGsFromFileInternal.GetImage("pack://application:,,,/DnProcessSimulateCommands;component/ImportMFGsFromFile/Resources/error.ico");
      return this.errorIco;
    }
  }

  public ResourceManager ResourceMgr => this.resMgr;

  private IMFFLogCode[] WarningCodesToLogInParsingPhase
  {
    get
    {
      return new IMFFLogCode[3]
      {
        IMFFLogCode.COLUMN_NOT_USED,
        IMFFLogCode.MISSING_ATTRIBUTE,
        IMFFLogCode.RELATION_ATTRIBUTES
      };
    }
  }

  private IMFFLogCode[] WarningCodesToLogInImportingPhase => (IMFFLogCode[]) null;

  private IMFFLogCode[] ErrorCodesToLogInParsingPhase => (IMFFLogCode[]) null;

  private IMFFLogCode[] ErrorCodesToLogInImportingPhase => (IMFFLogCode[]) null;

  private IMFFLogCode[] InfoCodesToLogInImportingPhase => (IMFFLogCode[]) null;

  internal string LastBrowsedDirectory
  {
    get
    {
      return Directory.Exists(CApImportMFGsFromFileInternal.lastBrowserDir) ? CApImportMFGsFromFileInternal.lastBrowserDir : TxApplication.SystemRootDirectoryNormalized;
    }
    set => CApImportMFGsFromFileInternal.lastBrowserDir = value;
  }

  public string LogPathLocation => Path.GetTempPath() + "ImportMFGsFromFile.log";

  private int DigitsAfterDecimalPoint => TxApplication.Options.Units.LinearDigitsAfterDecimalPoint;

  private double LinearMultiplier => TxApplication.Options.Units.LinearMultiplier;

  private bool HasLeadingPart
  {
    get => CApIMFFCSVParser.HeaderColumnsMapping.ContainsKey(CSVFileColumnHeaders.LEADING_PART);
  }

  private bool HasAssignedParts
  {
    get => CApIMFFCSVParser.HeaderColumnsMapping.ContainsKey(CSVFileColumnHeaders.CONNECTED_PARTS);
  }

  private bool HasAttributes
  {
    get => CApIMFFCSVParser.HeaderColumnsMapping.ContainsKey(CSVFileColumnHeaders.ATTRIBUTES);
  }

  private bool HasClass
  {
    get => CApIMFFCSVParser.HeaderColumnsMapping.ContainsKey(CSVFileColumnHeaders.CLASS);
  }

  private void LogMessages(
    string preMessage,
    SortedDictionary<IMFFLogCode, List<string>> messages,
    IMFFLogCode[] codesToLog = null)
  {
    if (codesToLog == null)
      codesToLog = messages.Keys.ToArray<IMFFLogCode>();
    if (messages.Count <= 0 || !messages.Keys.Any<IMFFLogCode>((Func<IMFFLogCode, bool>) (a => ((IEnumerable<IMFFLogCode>) codesToLog).Contains<IMFFLogCode>(a))))
      return;
    if (preMessage != null)
      this.logger.LogMessage(preMessage);
    foreach (IMFFLogCode key in codesToLog)
    {
      if (messages.ContainsKey(key))
      {
        messages[key].ForEach((Action<string>) (a => this.logger.LogCustom(new string(new char[1]
        {
          '\t'
        }), a)));
        this.logger.LogNewLine();
      }
      messages.Remove(key);
    }
  }

  private void ClearMembers()
  {
    this.warningsNumber = 0;
    this.errorsNumber = 0;
    this.MFGsCreatedNumber = 0;
    this.MFGsUpdatedNumber = 0;
    this.errors.Clear();
    this.warnings.Clear();
    this.infos.Clear();
    this.weldPointsList.Clear();
    this.weldPointsNumberToImport.Clear();
    this.attributesManager.Clear();
    this.m_csvFileNameToWeldOperation.Clear();
    this.m_csvFileNameToWeldPointsNames.Clear();
    this.m_csvFilesSuccessfullyParsed.Clear();
  }

  private void PrintSummary()
  {
    string str1 = string.Format(this.ResourceMgr.GetString("IMFF_WARNINGS_STATUS"), (object) this.warningsNumber);
    string str2 = string.Format(this.ResourceMgr.GetString("IMFF_ERRORS_STATUS"), (object) this.errorsNumber);
    string str3 = string.Format(this.ResourceMgr.GetString("IMFF_MFGS_IMPORTED"), (object) this.MFGsCreatedNumber);
    string str4 = string.Format(this.ResourceMgr.GetString("IMFF_MFGS_UPDATED"), (object) this.MFGsUpdatedNumber);
    string str5 = this.warningsNumber > 0 || this.errorsNumber > 0 ? this.ResourceMgr.GetString("IMFF_SEE_ABOVE") : "";
    this.LogMessage(string.Format(this.ResourceMgr.GetString("IMFF_IMPORT_FINISHED_WITH"), (object) $"{str3} {str4}", (object) str2, (object) str1, (object) str5));
  }

  private void FinalizeParser()
  {
    this.parser.OnLineParsed -= new OnLineParsedEventHandler(this.parser_OnLineParsed);
    this.parser.OnParsingProblem -= new OnParsingProblemEventHandler(this.parser_OnParsingProblem);
    this.parser = (CApIMFFCSVParser) null;
  }

  private List<KeyValuePair<TxPlanningTypeFieldData, string>> GetParsedAttributes(
    string[] parsedLine,
    string className)
  {
    List<KeyValuePair<string, string>> attributes = this.GetAttributes(parsedLine);
    if (attributes == null)
      return (List<KeyValuePair<TxPlanningTypeFieldData, string>>) null;
    List<KeyValuePair<TxPlanningTypeFieldData, string>> parsedAttributes = new List<KeyValuePair<TxPlanningTypeFieldData, string>>();
    TxPlanningTypeMetaData typeMetaData = TxApplication.ActiveDocument.PlatformGlobalServicesProvider.GetTypeMetaData(className);
    if (typeMetaData != null)
    {
      foreach (KeyValuePair<string, string> keyValuePair in attributes)
      {
        string key1 = keyValuePair.Key;
        TxPlanningTypeFieldData attributeField = (TxPlanningTypeFieldData) null;
        bool flag1 = this.attributesManager.IsHandledAttribute(className, key1);
        bool flag2 = this.attributesManager.IsInvalidAttribute(className, key1);
        if (!flag1)
        {
          if (!flag2)
          {
            try
            {
              attributeField = typeMetaData.Field(key1, true);
            }
            catch (TxPlanningObjectFieldDoesNotExistException ex)
            {
              this.AddWarningError(IMFFLogCode.MISSING_ATTRIBUTE, string.Format(IMFFResources.IMFF_MISSING_ATTRIBUTES_FORMAT, (object) key1, (object) className));
              this.attributesManager.AddInvalidAttribute(className, key1);
              flag2 = true;
            }
            if (attributeField != null)
            {
              if (attributeField.IsRelation)
              {
                if (!this.attributesManager.IsHandledRelationAttribute(key1))
                  this.AddWarning(IMFFLogCode.RELATION_ATTRIBUTES, $"\"{key1}\"");
                this.attributesManager.AddInvalidAttribute(className, key1);
                flag2 = true;
              }
              else
                this.attributesManager.AddAttribute(className, key1, attributeField);
            }
          }
        }
        if (!flag2)
        {
          TxPlanningTypeFieldData key2 = attributeField == null ? this.attributesManager.GetAttributeField(className, key1) : attributeField;
          parsedAttributes.Add(new KeyValuePair<TxPlanningTypeFieldData, string>(key2, keyValuePair.Value));
        }
      }
    }
    return parsedAttributes;
  }

  private void InitParser()
  {
    this.parser = new CApIMFFCSVParser();
    this.parser.OnLineParsed += new OnLineParsedEventHandler(this.parser_OnLineParsed);
    this.parser.OnParsingProblem += new OnParsingProblemEventHandler(this.parser_OnParsingProblem);
  }

  private void LogMessage(string message) => this.logger.LogMessage(message);

  private void AddWarning(IMFFLogCode code, string message)
  {
    ++this.warningsNumber;
    if (!this.warnings.ContainsKey(code))
    {
      this.warnings.Add(code, new List<string>());
      switch (code)
      {
        case IMFFLogCode.COLUMN_NOT_USED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_COLUMN_NOT_USED"));
          break;
        case IMFFLogCode.PART_NOT_FOUND:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_PART_NOT_FOUND"));
          break;
        case IMFFLogCode.LEADING_PART_VALUE_MISSING:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_MISSING_LEADING_PART"));
          break;
        case IMFFLogCode.LEADING_PART_NOT_FOUND_PARTS_NOT_ASSIGNED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_LEADING_PART_NOT_FOUND"));
          break;
        case IMFFLogCode.MISSING_ATTRIBUTE:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_MISSING_ATTRIBUTES"));
          break;
        case IMFFLogCode.RELATION_ATTRIBUTES:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_RELATION_ATTRIBUTES"));
          break;
        case IMFFLogCode.VALUE_TYPE_MISMATCH:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_VALUE_TYPE_MISMATCH"));
          break;
        case IMFFLogCode.CREATION_FAILED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_CREATION_FAILED"));
          break;
        case IMFFLogCode.PART_ASSIGNMENT_FAILED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_PART_ASSIGNMENT_FAILED"));
          break;
        case IMFFLogCode.ATTRIBUTE_ASSIGNMENT_FAILED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_ATTRIBUTE_ASSIGNMENT_FAILED"));
          break;
        case IMFFLogCode.CANNOT_PARSE_LINE:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_CANNOT_PARSE_LINE"));
          break;
        case IMFFLogCode.MULTIPLE_PARTS:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_MULTIPLE_PARTS"));
          break;
        case IMFFLogCode.MULTIPLE_MFGS_FIRST_UPDATED:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_MULTIPLE_MFGS_EXISTING"));
          break;
        case IMFFLogCode.INVALID_ROTATION:
          this.warnings[code].Add(this.ResourceMgr.GetString("IMFF_INVALID_ROTATION"));
          break;
      }
    }
    this.warnings[code].Add(message);
    this.FireOnWarningDetected();
  }

  private void AddInfo(IMFFLogCode code, string info)
  {
    if (!this.infos.ContainsKey(code))
    {
      this.infos.Add(code, new List<string>());
      switch (code)
      {
        case IMFFLogCode.EXISTING_MFGS_SKIPPED:
          this.infos[code].Add(this.ResourceMgr.GetString("IMFF_EXISTING_MFGS_SKIPPED"));
          break;
        case IMFFLogCode.EXISTING_MFGS_UPDATED:
          this.infos[code].Add(this.ResourceMgr.GetString("IMFF_EXISTING_MFGS_UPDATED"));
          break;
      }
    }
    this.infos[code].Add(info);
  }

  private void AddError(IMFFLogCode code, string error)
  {
    ++this.errorsNumber;
    if (!this.errors.ContainsKey(code))
    {
      this.errors.Add(code, new List<string>());
      switch (code)
      {
        case IMFFLogCode.INVALID_LOCATION:
          this.errors[code].Add(this.ResourceMgr.GetString("IMFF_INVALID_LOCATION"));
          break;
        case IMFFLogCode.MULTIPLE_MFGS_SKIPPING:
          this.errors[code].Add(this.ResourceMgr.GetString("IMFF_MULTIPLE_MFGS_IN_CSV"));
          break;
        case IMFFLogCode.INVALID_CLASS:
          this.errors[code].Add(this.ResourceMgr.GetString("IMFF_INVALID_CLASS"));
          break;
        case IMFFLogCode.NOT_DERIVED_CLASS:
          this.errors[code].Add(this.ResourceMgr.GetString("IMFF_NOT_DERIVED_CLASS"));
          break;
        case IMFFLogCode.INVALID_LOCATION_AFTER_CALCULATION:
          this.errors[code].Add(this.ResourceMgr.GetString("IMFF_INVALID_LOCATION_AFTER_CALCULATION"));
          break;
      }
    }
    this.errors[code].Add(error);
    this.FireOnErrorDetected();
  }

  private void InitLogger(string filePath)
  {
    this.logger = CApIMFFLogManager.Logger;
    this.logger.Init(filePath);
  }

  private void LogCurrentFile(string csvFileName)
  {
    this.logger.LogMessage($"{(!TxTcUtilities.IsTcAnyPlatform ? IMFFResources.IMFF_DESCRIPTION : IMFFResources.IMFF_TC_DESCRIPTION)} \"{csvFileName}\"");
    this.logger.LogMessage("------------------------------------------------");
  }

  private void FinalizeLogger() => this.logger.Close();

  private void AddWarningError(IMFFLogCode code, string message)
  {
    switch (code)
    {
      case IMFFLogCode.COLUMN_NOT_USED:
      case IMFFLogCode.PART_NOT_FOUND:
      case IMFFLogCode.LEADING_PART_VALUE_MISSING:
      case IMFFLogCode.LEADING_PART_NOT_FOUND_PARTS_NOT_ASSIGNED:
      case IMFFLogCode.MISSING_ATTRIBUTE:
      case IMFFLogCode.RELATION_ATTRIBUTES:
      case IMFFLogCode.VALUE_TYPE_MISMATCH:
      case IMFFLogCode.CREATION_FAILED:
      case IMFFLogCode.MISSING_LEADING_PART:
      case IMFFLogCode.PART_ASSIGNMENT_FAILED:
      case IMFFLogCode.ATTRIBUTE_ASSIGNMENT_FAILED:
      case IMFFLogCode.CANNOT_PARSE_LINE:
      case IMFFLogCode.MULTIPLE_PARTS:
      case IMFFLogCode.MULTIPLE_MFGS_FIRST_UPDATED:
      case IMFFLogCode.INVALID_ROTATION:
        this.AddWarning(code, message);
        break;
      case IMFFLogCode.INVALID_LOCATION:
      case IMFFLogCode.MULTIPLE_COLUMNS:
      case IMFFLogCode.MISSING_COLUMN_HEADER:
      case IMFFLogCode.FILE_CANNOT_BE_OPENED:
      case IMFFLogCode.GENERAL_ERROR:
      case IMFFLogCode.MULTIPLE_MFGS_SKIPPING:
      case IMFFLogCode.INVALID_CLASS:
      case IMFFLogCode.NOT_DERIVED_CLASS:
      case IMFFLogCode.INVALID_LOCATION_AFTER_CALCULATION:
        this.AddError(code, message);
        break;
      case IMFFLogCode.EXISTING_MFGS_SKIPPED:
      case IMFFLogCode.EXISTING_MFGS_UPDATED:
        this.AddInfo(code, message);
        break;
    }
  }

  private void parser_OnParsingProblem(object sender, OnParsingProblemEventArgs args)
  {
    this.AddWarningError(args.Result, args.Message);
  }

  private void parser_OnLineParsed(object sender, OnLineParsedEventArgs args)
  {
    if (!this.IsClassValid(args.LineParsed, args.LineNumber))
      return;
    string[] lineParsed1 = args.LineParsed;
    KeyValuePair<int, string> keyValuePair = CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.X][0];
    int key1 = keyValuePair.Key;
    double x = double.Parse(lineParsed1[key1]);
    string[] lineParsed2 = args.LineParsed;
    keyValuePair = CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.Y][0];
    int key2 = keyValuePair.Key;
    double y = double.Parse(lineParsed2[key2]);
    string[] lineParsed3 = args.LineParsed;
    keyValuePair = CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.Z][0];
    int key3 = keyValuePair.Key;
    double z = double.Parse(lineParsed3[key3]);
    TxVector locationAccordingToXyz = this.CreateLocationAccordingToXYZ(x, y, z);
    TxVector rotation = this.GetRotation(args.LineParsed);
    TxTransformation txTransformation = new TxTransformation(locationAccordingToXyz, rotation, (TxTransformation.TxRotationType) 1);
    if (this.UseWorkingFrame)
      txTransformation = TxTransformation.op_Multiply(TxApplication.ActiveDocument.WorkingFrame, txTransformation);
    string str = args.LineParsed[CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.NAME][0].Key];
    TxVector translation = txTransformation.Translation;
    if (!this.IsValidTranslationForMfg(translation))
    {
      this.AddWarningError(IMFFLogCode.INVALID_LOCATION_AFTER_CALCULATION, string.Format(this.ResourceMgr.GetString("IMFF_INVALID_LOCATION_FORMAT"), (object) args.LineNumber, (object) str, (object) translation.X, (object) translation.Y, (object) translation.Z));
    }
    else
    {
      TxWeldPointCreationData pointCreationData = (TxWeldPointCreationData) TxMfgCreationDataFactory.CreateWeldPointCreationData(str, txTransformation);
      pointCreationData.PlanningType = this.GetClass(args.LineParsed);
      List<string> connectedParts = this.GetConnectedParts(args.LineParsed);
      if (connectedParts[0] == "" && connectedParts.Count > 1)
      {
        connectedParts.Clear();
        this.AddWarningError(IMFFLogCode.LEADING_PART_VALUE_MISSING, string.Format(this.ResourceMgr.GetString("IMFF_LEADING_PART_VALUE_MISSING_FORMAT"), (object) args.LineNumber, (object) ((TxObjectCreationData) pointCreationData).Name));
      }
      List<KeyValuePair<TxPlanningTypeFieldData, string>> parsedAttributes = this.GetParsedAttributes(args.LineParsed, pointCreationData.PlanningType);
      this.weldPointsList.Add(Tuple.Create<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int>(pointCreationData, connectedParts, parsedAttributes, rotation, args.LineNumber));
      if (!this.weldPointsNumberToImport.ContainsKey(((TxObjectCreationData) pointCreationData).Name))
        this.weldPointsNumberToImport.Add(((TxObjectCreationData) pointCreationData).Name, 0);
      this.weldPointsNumberToImport[((TxObjectCreationData) pointCreationData).Name]++;
      ++this.LinesParsed;
      string withoutExtension = Path.GetFileNameWithoutExtension(args.FilePath);
      if (!this.m_csvFileNameToWeldPointsNames.ContainsKey(withoutExtension))
        this.m_csvFileNameToWeldPointsNames.Add(withoutExtension, new List<string>());
      this.m_csvFileNameToWeldPointsNames[withoutExtension].Add(((TxObjectCreationData) pointCreationData).Name);
    }
  }

  private List<string> GetConnectedParts(string[] parsedLine)
  {
    List<string> connectedParts = new List<string>();
    connectedParts.Add(this.GetLeadingPart(parsedLine));
    if (this.HasAssignedParts)
    {
      foreach (KeyValuePair<int, string> keyValuePair in CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.CONNECTED_PARTS])
      {
        int key = keyValuePair.Key;
        if (parsedLine.Length > key && parsedLine[key].Length > 0)
          connectedParts.Add(parsedLine[key]);
      }
    }
    return connectedParts;
  }

  private string GetLeadingPart(string[] parsedLine)
  {
    string leadingPart = "";
    if (this.HasLeadingPart && parsedLine.Length > CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.LEADING_PART][0].Key)
      leadingPart = parsedLine[CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.LEADING_PART][0].Key];
    return leadingPart;
  }

  private List<KeyValuePair<string, string>> GetAttributes(string[] parsedLine)
  {
    List<KeyValuePair<string, string>> attributes = (List<KeyValuePair<string, string>>) null;
    if (this.HasAttributes)
    {
      attributes = new List<KeyValuePair<string, string>>();
      foreach (KeyValuePair<int, string> keyValuePair in CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.ATTRIBUTES])
      {
        int key1 = keyValuePair.Key;
        string key2 = keyValuePair.Value;
        if (parsedLine.Length > key1 && parsedLine[key1].Length > 0)
          attributes.Add(new KeyValuePair<string, string>(key2, parsedLine[key1]));
      }
    }
    return attributes;
  }

  private string GetWeldPointBaseClass()
  {
    return TxTcUtilities.IsTcAnyPlatform ? "WeldPointRevision" : "PmWeldPoint";
  }

  private string GetClass(string[] parsedLine)
  {
    string str1 = "";
    if (this.HasClass && parsedLine.Length > CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.CLASS][0].Key)
      str1 = parsedLine[CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.CLASS][0].Key];
    string str2 = str1.Trim();
    if (string.IsNullOrWhiteSpace(str2))
      str2 = this.GetWeldPointBaseClass();
    else if (TxTcUtilities.IsTcAnyPlatform && str2 == "WeldPoint")
      str2 = "WeldPointRevision";
    return str2;
  }

  private bool IsClassValid(string[] parsedLine, int lineNum)
  {
    bool flag = true;
    string str1 = parsedLine[CApIMFFCSVParser.HeaderColumnsMapping[CSVFileColumnHeaders.NAME][0].Key];
    string str2 = this.GetClass(parsedLine);
    if (str2 != "")
    {
      TxPlanningTypeMetaData typeMetaData = TxApplication.ActiveDocument.PlatformGlobalServicesProvider.GetTypeMetaData(str2);
      if (typeMetaData == null)
      {
        flag = false;
        this.AddWarningError(IMFFLogCode.INVALID_CLASS, string.Format(IMFFResources.IMFF_INVALID_CLASS_FORMAT, (object) lineNum, (object) str1, (object) str2));
      }
      else if (!typeMetaData.IsDerivedFromPlanningType(this.GetWeldPointBaseClass()))
      {
        flag = false;
        this.AddWarningError(IMFFLogCode.NOT_DERIVED_CLASS, string.Format(IMFFResources.IMFF_INVALID_CLASS_FORMAT, (object) lineNum, (object) str1, (object) str2));
      }
    }
    return flag;
  }

  private TxVector GetRotation(string[] parsedLine)
  {
    return new TxVector()
    {
      X = this.GetRotationValue(parsedLine, CSVFileColumnHeaders.RX),
      Y = this.GetRotationValue(parsedLine, CSVFileColumnHeaders.RY),
      Z = this.GetRotationValue(parsedLine, CSVFileColumnHeaders.RZ)
    };
  }

  private double GetRotationValue(string[] parsedLine, CSVFileColumnHeaders column)
  {
    double rotationValue = 0.0;
    if (CApIMFFCSVParser.HeaderColumnsMapping.ContainsKey(column))
    {
      int length = parsedLine.Length;
      KeyValuePair<int, string> keyValuePair = CApIMFFCSVParser.HeaderColumnsMapping[column][0];
      int key1 = keyValuePair.Key;
      if (length > key1)
      {
        string[] strArray = parsedLine;
        keyValuePair = CApIMFFCSVParser.HeaderColumnsMapping[column][0];
        int key2 = keyValuePair.Key;
        double result;
        if (double.TryParse(strArray[key2], out result))
          rotationValue = result;
      }
    }
    return rotationValue;
  }

  private void AssignPartsToLocOper(TxWeldLocationOperation locOp, List<string> parts, int lNum)
  {
    if (this.HasLeadingPart)
    {
      locOp.Detach();
      ((TxMfgFeature) locOp.WeldPoint).ClearAssignedParts();
    }
    this.FindAndReportMultipleParts(locOp, parts, lNum);
    Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
    TxObjectList txObjectList = new TxObjectList();
    string part = parts[0];
    ITxComponent itxComponent = (ITxComponent) null;
    if (part != "")
    {
      itxComponent = this.GetPartByName(parts[0]);
      if (itxComponent != null)
      {
        ((Collection<ITxObject>) txObjectList).Add((ITxObject) itxComponent);
        locOp.WeldPoint.LeadingPart = (ITxLeadingPart) itxComponent;
        locOp.AttachTo(itxComponent as ITxLocatableObject);
      }
      dictionary.Add(part, itxComponent != null);
    }
    parts.RemoveAt(0);
    if (parts.Count > 0)
    {
      TxObjectList partsByNames = this.GetPartsByNames(parts, dictionary);
      if (itxComponent == null)
      {
        this.AddWarningError(IMFFLogCode.LEADING_PART_NOT_FOUND_PARTS_NOT_ASSIGNED, string.Format(this.ResourceMgr.GetString("IMFF_LEADING_PART_NOT_FOUND_FORMAT"), (object) lNum, (object) locOp.Name, (object) part));
        dictionary[part] = true;
      }
      else
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) partsByNames);
    }
    this.ReportMissingParts(dictionary, locOp, lNum);
    ((TxMfgFeature) locOp.WeldPoint).AssignParts(txObjectList);
  }

  private void ReportMissingParts(
    Dictionary<string, bool> partsExistance,
    TxWeldLocationOperation mfg,
    int lNum)
  {
    Dictionary<string, bool>.Enumerator enumerator = partsExistance.GetEnumerator();
    string str1 = "";
    while (enumerator.MoveNext())
    {
      KeyValuePair<string, bool> current = enumerator.Current;
      if (!current.Value)
      {
        string str2 = str1;
        current = enumerator.Current;
        string key = current.Key;
        str1 = $"{str2}, \"{key}\"";
      }
    }
    if (!(str1 != ""))
      return;
    string str3 = str1.Substring(2, str1.Length - 2);
    this.AddWarningError(IMFFLogCode.PART_NOT_FOUND, string.Format(this.ResourceMgr.GetString("IMFF_PART_NOT_FOUND_FORMAT"), (object) lNum, (object) mfg.Name, (object) str3));
  }

  private void AssignAttributesToLocOper(
    TxWeldLocationOperation locOp,
    List<KeyValuePair<TxPlanningTypeFieldData, string>> attributes,
    int lNum)
  {
    ITxPlatformGlobalServicesProvider servicesProvider = TxApplication.ActiveDocument.PlatformGlobalServicesProvider;
    ITxPlanningObject planningRepresentation = ((TxMfgFeature) locOp.WeldPoint).PlanningRepresentation;
    TxPlanningTypeMetaData planningTypeMetaData = (TxPlanningTypeMetaData) null;
    if (planningRepresentation != null)
      planningTypeMetaData = servicesProvider.GetTypeMetaData(planningRepresentation.PlanningType);
    if (planningTypeMetaData == null)
      return;
    string str1 = "";
    string str2 = "";
    foreach (KeyValuePair<TxPlanningTypeFieldData, string> attribute in attributes)
    {
      TxPlanningFieldType valueType = attribute.Key.ValueType;
      string name = attribute.Key.Name;
      object fieldValue1 = (object) null;
      try
      {
        fieldValue1 = this.ConvertFieldValueToType(attribute.Value, valueType);
      }
      catch (FormatException ex)
      {
        str1 += string.Format(this.ResourceMgr.GetString("IMFF_ATTRIBUTE_TYPE_VALUE"), (object) name, (object) attribute.Value);
      }
      try
      {
        if (fieldValue1 != null)
        {
          object fieldValue2 = this.GetFieldValue(planningRepresentation, name);
          TxPlanningObjectExtensions.ComputeField((ITxPlanningObject) (planningRepresentation as TxPlanningObject), name, fieldValue1);
          this.UpdateRoboticParamsMappedToMfgFields((ITxRoboticOperation) locOp, planningRepresentation as TxPlanningMfgFeature, name, valueType, fieldValue2, fieldValue1);
        }
      }
      catch (Exception ex)
      {
        str2 += string.Format(this.ResourceMgr.GetString("IMFF_ATTRIBUTE_TYPE_VALUE"), (object) name, (object) attribute.Value);
      }
    }
    if (str1 != "")
      this.AddWarning(IMFFLogCode.VALUE_TYPE_MISMATCH, string.Format(this.ResourceMgr.GetString("IMFF_VALUE_TYPE_MISMATCH_FORMAT"), (object) lNum, (object) locOp.Name, (object) str1));
    if (!(str2 != ""))
      return;
    this.AddWarning(IMFFLogCode.ATTRIBUTE_ASSIGNMENT_FAILED, string.Format(this.ResourceMgr.GetString("IMFF_VALUE_TYPE_MISMATCH_FORMAT"), (object) lNum, (object) locOp.Name, (object) str2));
  }

  private object ConvertFieldValueToType(string fieldValue, TxPlanningFieldType fieldType)
  {
    string[] strArray = fieldValue.Split(CApIMFFCSVParser.DELIMITER);
    object type = (object) null;
    switch (fieldType - 1)
    {
      case 0:
        type = (object) Convert.ToBoolean(fieldValue);
        break;
      case 1:
        type = (object) Convert.ToInt32(fieldValue);
        break;
      case 2:
        type = (object) Convert.ToInt64(fieldValue);
        break;
      case 3:
        type = (object) Convert.ToSingle(fieldValue);
        break;
      case 4:
        type = (object) Convert.ToDouble(fieldValue);
        break;
      case 5:
        type = (object) fieldValue;
        break;
      case 6:
        type = (object) TxVector.Parse(fieldValue);
        break;
      case 7:
        type = (object) TxTransformation.Parse(fieldValue);
        break;
      case 8:
        type = (object) (TxApplication.ActiveDocument.GetObjectByProcessModelId(new TxProcessModelId(fieldValue)) as TxPlanningObject);
        break;
      case 9:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToBoolean(str));
        break;
      case 10:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToInt32(str));
        break;
      case 11:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToInt64(str));
        break;
      case 12:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToSingle(str));
        break;
      case 13:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToDouble(str));
        break;
      case 14:
        type = (object) new ArrayList();
        (type as ArrayList).AddRange((ICollection) fieldValue.Split(CApIMFFCSVParser.DELIMITER));
        IEnumerator enumerator = (type as ArrayList).GetEnumerator();
        try
        {
          while (enumerator.MoveNext())
            ((string) enumerator.Current).Trim();
          break;
        }
        finally
        {
          if (enumerator is IDisposable disposable)
            disposable.Dispose();
        }
      case 17:
        type = (object) new ArrayList();
        foreach (string str in strArray)
        {
          ITxObject byProcessModelId = TxApplication.ActiveDocument.GetObjectByProcessModelId(new TxProcessModelId(str));
          (type as ArrayList).Add((object) (byProcessModelId as TxPlanningObject));
        }
        break;
      case 18:
        type = (object) Convert.ToInt16(fieldValue);
        break;
      case 19:
        type = (object) new ArrayList();
        foreach (string str in strArray)
          (type as ArrayList).Add((object) Convert.ToInt16(str));
        break;
      case 20:
        type = (object) Convert.ToDateTime(fieldValue);
        break;
    }
    return type;
  }

  private object GetFieldValue(ITxPlanningObject planningObject, string fieldName)
  {
    object fieldValue = (object) null;
    if (planningObject.FieldWasImported(fieldName))
      fieldValue = planningObject.GetField(fieldName);
    return fieldValue;
  }

  private void UpdateRoboticParamsMappedToMfgFields(
    ITxRoboticOperation robOper,
    TxPlanningMfgFeature planningMfgObject,
    string fieldName,
    TxPlanningFieldType fieldType,
    object oldFieldValue,
    object fieldValue)
  {
    if (planningMfgObject == null)
      return;
    string nameMappedToField = TxPlanningObjectExtensions.GetRoboticParameterNameMappedToField(planningMfgObject, fieldName);
    if (!(nameMappedToField != string.Empty))
      return;
    TxRoboticParam parameter = robOper.GetParameter(nameMappedToField);
    if (parameter == null || oldFieldValue == null)
      return;
    PlanningFieldToRoboticParamComparator roboticParamComparator = new PlanningFieldToRoboticParamComparator();
    if (!roboticParamComparator.ComparePlanningFieldToRoboticParamValue(fieldType, oldFieldValue, parameter))
      return;
    robOper.SetParameter(roboticParamComparator.CreateRoboticParamFromMappedMfgField(parameter, fieldType, fieldValue));
  }

  private TxVector CreateLocationAccordingToXYZ(double x, double y, double z)
  {
    return new TxVector()
    {
      X = this.LinearMultiplier * Math.Round(x, this.DigitsAfterDecimalPoint),
      Y = this.LinearMultiplier * Math.Round(y, this.DigitsAfterDecimalPoint),
      Z = this.LinearMultiplier * Math.Round(z, this.DigitsAfterDecimalPoint)
    };
  }

  private bool CanCreateWeldOperation(ITxObject parent)
  {
    bool weldOperation = false;
    ITxOperationCreation operationCreation1 = parent as ITxOperationCreation;
    ITxTcOperationCreation operationCreation2 = parent as ITxTcOperationCreation;
    if (!weldOperation && operationCreation1 != null)
      weldOperation = operationCreation1.CanCreateChildOperationOfType(typeof (TxWeldOperation));
    if (!weldOperation && operationCreation2 != null)
    {
      using (TxTcDiscreteOperationCreationData operationCreationData = new TxTcDiscreteOperationCreationData())
        weldOperation = operationCreation2.CanCreateTcDiscreteOperation(operationCreationData);
    }
    return weldOperation;
  }

  private ITxObject GetParentOperationToCreateWeldOperationsUnder()
  {
    ITxObject weldOperationsUnder = (ITxObject) null;
    ITxOperation currentOperation = TxApplication.ActiveDocument.CurrentOperation;
    if (this.CanCreateWeldOperation((ITxObject) currentOperation))
      weldOperationsUnder = (ITxObject) currentOperation;
    if (weldOperationsUnder == null)
    {
      if (TxTcUtilities.IsTcAnyPlatform)
      {
        ITxObjectCollection operationRoot = (ITxObjectCollection) TxApplication.ActiveDocument.OperationRoot;
        if (operationRoot != null)
        {
          ITxTypeFilter itxTypeFilter = (ITxTypeFilter) new TxTypeFilter(new Type[2]
          {
            typeof (ITxTcOperationCreation),
            typeof (ITxOperationCreation)
          });
          weldOperationsUnder = ((IEnumerable<ITxObject>) operationRoot.GetDirectDescendants(itxTypeFilter)).FirstOrDefault<ITxObject>((Func<ITxObject, bool>) (x => this.CanCreateWeldOperation(x)));
        }
      }
      else
        weldOperationsUnder = (ITxObject) TxApplication.ActiveDocument.OperationRoot;
    }
    return weldOperationsUnder;
  }

  private TxWeldLocationOperationCreationData CreateWeldLocationOperationCreationData(
    ITxWeldPointCreationData wp)
  {
    return new TxWeldLocationOperationCreationData()
    {
      WeldPointCreationData = wp,
      Name = ((ITxObjectCreationData) wp).Name
    };
  }

  internal void CreateWeldPointsInTuneByCreationData()
  {
    this.LogMessage(this.ResourceMgr.GetString("IMFF_IMPORTING_MFGS"));
    this.FireOnImportStatusChanged(ImportStatus.ImportingMFGs);
    try
    {
      if (this.m_csvFilesSuccessfullyParsed.Count != 0 && this.m_csvFileNameToWeldOperation.Count == 0)
        throw new Exception(this.ResourceMgr.GetString("IMFF_CONTAINER_NOT_FOUND"));
      this.PopulateExistingMfgs();
      if (this.CommandMode == ImportMode.NOT_DEFINED)
        this.CommandMode = this.CheckMfgExistance();
      if (this.CommandMode == ImportMode.CANCEL)
        throw new Exception(this.ResourceMgr.GetString("IMFF_IMPORT_ABORT"));
      this.partsUnderPhysicalRoot = this.GetPartComponents();
      TxWeldLocationOperation locOp = (TxWeldLocationOperation) null;
      foreach (Tuple<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int> weldPoints in this.weldPointsList)
      {
        string message = string.Format(this.ResourceMgr.GetString("IMFF_CREATION_FAILED_FORMAT"), (object) weldPoints.Item5, (object) ((TxObjectCreationData) weldPoints.Item1).Name);
        if (this.weldPointsNumberToImport[((TxObjectCreationData) weldPoints.Item1).Name] > 1)
        {
          this.AddWarningError(IMFFLogCode.MULTIPLE_MFGS_SKIPPING, message);
        }
        else
        {
          if (!this.existingMfgs.ContainsKey(((TxObjectCreationData) weldPoints.Item1).Name))
          {
            using (TxWeldLocationOperationCreationData wlcd = this.CreateWeldLocationOperationCreationData((ITxWeldPointCreationData) weldPoints.Item1))
            {
              string key = this.m_csvFileNameToWeldPointsNames.FirstOrDefault<KeyValuePair<string, List<string>>>((Func<KeyValuePair<string, List<string>>, bool>) (item => item.Value.Contains(wlcd.Name))).Key;
              if (this.m_csvFileNameToWeldOperation.ContainsKey(key))
              {
                if (this.m_csvFileNameToWeldOperation[key].CanCreateWeldLocationOperation(wlcd))
                {
                  locOp = this.m_csvFileNameToWeldOperation[key].CreateWeldLocationOperation(wlcd);
                  ++this.MFGsCreatedNumber;
                }
                else
                  this.AddWarningError(IMFFLogCode.CREATION_FAILED, message);
              }
            }
            if (TxWeldLocationOperation.op_Equality(locOp, (ITxObject) null))
              continue;
          }
          else
          {
            if (this.CommandMode == ImportMode.IMPORT)
            {
              this.AddWarningError(IMFFLogCode.EXISTING_MFGS_SKIPPED, message);
              continue;
            }
            if (this.existingMfgs[((TxObjectCreationData) weldPoints.Item1).Name].Count > 1)
              this.AddWarningError(IMFFLogCode.MULTIPLE_MFGS_FIRST_UPDATED, message);
            else
              this.AddWarningError(IMFFLogCode.EXISTING_MFGS_UPDATED, message);
            TxMfgFeature txMfgFeature = this.existingMfgs[((TxObjectCreationData) weldPoints.Item1).Name][0] as TxMfgFeature;
            if (TxMfgFeature.op_Inequality(txMfgFeature, (ITxObject) null) && txMfgFeature.AssignedOperations != null && ((Collection<ITxObject>) txMfgFeature.AssignedOperations).Count > 0)
              locOp = ((Collection<ITxObject>) txMfgFeature.AssignedOperations)[0] as TxWeldLocationOperation;
            if (TxWeldLocationOperation.op_Equality(locOp, (ITxObject) null))
            {
              this.AddWarningError(IMFFLogCode.GENERAL_ERROR, this.ResourceMgr.GetString("IMFF_GENERAL_ERROR"));
              continue;
            }
            TxVector position = weldPoints.Item1.Position;
            TxVector rot = weldPoints.Item4;
            if (!locOp.IsProjected)
            {
              this.SetLocation((ITxLocatableObject) locOp, position, rot);
            }
            else
            {
              TxVector translation = txMfgFeature?.AbsoluteLocation.Translation;
              TxVector rotationRpyXyz = txMfgFeature?.AbsoluteLocation.RotationRPY_XYZ;
              if (TxVector.op_Inequality(position, translation) || TxVector.op_Inequality(rot, rotationRpyXyz))
                locOp.SetProjectionAsInvalid((TxInvalidProjectionReason) 1);
            }
            this.SetLocation((ITxLocatableObject) locOp.WeldPoint, position, rot);
            ++this.MFGsUpdatedNumber;
          }
          if (weldPoints.Item2 != null && weldPoints.Item2.Count > 0)
            this.AssignPartsToLocOper(locOp, weldPoints.Item2, weldPoints.Item5);
          if (weldPoints.Item3 != null)
            this.AssignAttributesToLocOper(locOp, weldPoints.Item3, weldPoints.Item5);
          this.FireOnMFGImported();
        }
      }
    }
    catch (Exception ex)
    {
      this.AddWarningError(IMFFLogCode.GENERAL_ERROR, ex.Message);
    }
    finally
    {
      this.ClearEmptyWeldOperations();
      this.LogMessages((string) null, this.infos, this.InfoCodesToLogInImportingPhase);
      this.LogMessages(this.ResourceMgr.GetString("IMFF_ERRORS"), this.errors, this.ErrorCodesToLogInImportingPhase);
      this.LogMessages(this.ResourceMgr.GetString("IMFF_PARSING_WARNINGS_OCCURED"), this.warnings, this.WarningCodesToLogInImportingPhase);
      this.LogMessage(this.ResourceMgr.GetString("IMFF_IMPORT_FINISHED"));
      this.LogMessage("------------------------------------------------");
    }
    this.txOperationTree.UnFreezeTree();
    TxApplication.RefreshDisplay();
  }

  private void ClearEmptyWeldOperations()
  {
    foreach (TxBaseWeldOperation baseWeldOperation in this.m_csvFileNameToWeldOperation.Values)
    {
      if (((Collection<ITxObject>) baseWeldOperation.GetAllDescendants((ITxTypeFilter) new TxNoTypeFilter())).Count == 0)
        baseWeldOperation.Delete();
    }
  }

  private void SetLocation(ITxLocatableObject obj, TxVector pos, TxVector rot)
  {
    if (obj == null)
      return;
    obj.AbsoluteLocation = new TxTransformation(pos, rot, (TxTransformation.TxRotationType) 1);
  }

  private void PopulateExistingMfgs()
  {
    this.existingMfgs.Clear();
    IEnumerable<ITxObject> source = ((IEnumerable<ITxObject>) TxApplication.ActiveDocument.MfgRoot.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(typeof (TxWeldPoint)))).AsEnumerable<ITxObject>();
    if (TxTcUtilities.IsTcAnyPlatform)
      source = source.Where<ITxObject>((Func<ITxObject, bool>) (wp => ((TxMfgFeature) (wp as TxWeldPoint)).IsPrivate()));
    foreach (Tuple<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int> weldPoints in this.weldPointsList)
    {
      Tuple<TxWeldPointCreationData, List<string>, List<KeyValuePair<TxPlanningTypeFieldData, string>>, TxVector, int> a = weldPoints;
      foreach (ITxObject itxObject in source.Where<ITxObject>((Func<ITxObject, bool>) (b => b.Name == ((TxObjectCreationData) a.Item1).Name)))
      {
        if (!this.existingMfgs.ContainsKey(itxObject.Name))
          this.existingMfgs.Add(itxObject.Name, new List<ITxObject>());
        this.existingMfgs[itxObject.Name].Add(itxObject);
      }
    }
  }

  private ImportMode CheckMfgExistance()
  {
    DialogResult dialogResult = DialogResult.Yes;
    foreach (KeyValuePair<string, List<ITxObject>> existingMfg in this.existingMfgs)
    {
      if (this.weldPointsNumberToImport[existingMfg.Key] == 1)
      {
        dialogResult = this.ShowConfirmMessage();
        break;
      }
    }
    int num;
    switch (dialogResult)
    {
      case DialogResult.Yes:
        num = 1;
        break;
      case DialogResult.No:
        num = 2;
        break;
      default:
        num = 3;
        break;
    }
    return (ImportMode) num;
  }

  private List<ITxObject> GetPartComponents()
  {
    List<ITxObject> list = ((IEnumerable<ITxObject>) TxApplication.ActiveDocument.PhysicalRoot.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(new Type[1]
    {
      typeof (ITxComponent)
    }))).ToList<ITxObject>();
    list.RemoveAll((Predicate<ITxObject>) (current => !(current is ITxProcessModelObject processModelObject) || processModelObject.PlanningRepresentation == null || processModelObject.PlanningRepresentation.PlanningObjectType > 0));
    return list;
  }

  private void FindAndReportMultipleParts(
    TxWeldLocationOperation mfg,
    List<string> assignedParts,
    int lNum)
  {
    HashSet<string> multipleParts = new HashSet<string>();
    List<ITxObject> parts = this.partsUnderPhysicalRoot;
    assignedParts.ForEach((Action<string>) (a =>
    {
      if (parts.FindAll((Predicate<ITxObject>) (b => b.Name == a)).Count <= 1 || multipleParts.Contains(a))
        return;
      multipleParts.Add(a);
    }));
    string str1 = "";
    HashSet<string>.Enumerator enumerator = multipleParts.GetEnumerator();
    while (enumerator.MoveNext())
      str1 = $"{str1}, \"{enumerator.Current}\"";
    if (!(str1 != ""))
      return;
    string str2 = str1.Substring(2, str1.Length - 2);
    this.AddWarningError(IMFFLogCode.MULTIPLE_PARTS, string.Format(this.ResourceMgr.GetString("IMFF_PART_NOT_FOUND_FORMAT"), (object) lNum, (object) mfg.Name, (object) str2));
  }

  private TxObjectList GetPartsByNames(
    List<string> partNames,
    Dictionary<string, bool> partNamesHash)
  {
    partNames.ForEach((Action<string>) (a =>
    {
      if (partNamesHash.ContainsKey(a))
        return;
      partNamesHash.Add(a, false);
    }));
    TxObjectList partsByNames = new TxObjectList();
    foreach (ITxObject itxObject in this.partsUnderPhysicalRoot)
    {
      if (itxObject is ITxProcessModelObject processModelObject && processModelObject.PlanningRepresentation.PlanningObjectType == null)
      {
        TxPartInstanceEx txPartInstanceEx = new TxPartInstanceEx(new TxProcessModelId(processModelObject.ProcessModelId));
        if (partNamesHash.ContainsKey(txPartInstanceEx.Name) && !partNamesHash[txPartInstanceEx.Name])
        {
          ((Collection<ITxObject>) partsByNames).Add(itxObject);
          partNamesHash[txPartInstanceEx.Name] = true;
        }
      }
    }
    return partsByNames;
  }

  private ITxComponent GetPartByName(string partName)
  {
    ITxComponent partByName = (ITxComponent) null;
    foreach (ITxObject itxObject in this.partsUnderPhysicalRoot)
    {
      if (itxObject is ITxProcessModelObject processModelObject && processModelObject.PlanningRepresentation.PlanningObjectType == null && new TxPartInstanceEx(new TxProcessModelId(processModelObject.ProcessModelId)).Name.Equals(partName))
      {
        partByName = itxObject as ITxComponent;
        break;
      }
    }
    return partByName;
  }

  private bool IsValidTranslationForMfg(TxVector translation)
  {
    return this.IsValidTranslationValue(translation.X) && this.IsValidTranslationValue(translation.Y) && this.IsValidTranslationValue(translation.Z);
  }

  private bool IsValidTranslationValue(double v) => v >= -999999.001 && v <= 999999.001;

  private void FireOnWarningDetected()
  {
    if (this.onWarningDetected == null)
      return;
    this.onWarningDetected((object) this, new EventArgs());
  }

  private void FireOnErrorDetected()
  {
    if (this.onErrorDetected == null)
      return;
    this.onErrorDetected((object) this, new EventArgs());
  }

  private void FireOnMFGImported()
  {
    if (this.onMFGImported == null)
      return;
    this.onMFGImported((object) this, new EventArgs());
  }

  private void FireOnImportStatusChanged(ImportStatus stat)
  {
    if (this.onImportStatusChanged == null)
      return;
    this.onImportStatusChanged((object) this, new OnImportStatusChangedEventArgs(stat));
  }
}
